package org.jasper.impl.service;


import org.jasper.api.service.ServiceRegistry;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Callable;

/**
 * Created by OP038074 on 2018/8/3.
 */
public class ServiceRegistryImpl implements ServiceRegistry {

    private final Map<String, Callable< ? >> registry = new HashMap<String, Callable< ? >>();
    private final Map<String, Callable< ? >> defaultServices = new HashMap<String, Callable< ? >>();

    private static final ServiceRegistry instance = new ServiceRegistryImpl();

    public static ServiceRegistry getInstance() {
        return instance;
    }

    public synchronized <T> T get(Class<T> cls) {

        Callable< ? > cal = this.registry.get( cls.getName() );
        if ( cal != null ) {
            try {
                return cls.cast( cal.call() );
            } catch ( Exception e ) {
                throw new IllegalArgumentException( "Unable to instantiate service for Class '" + (cls != null ? cls.getName() : null) + "'",
                        e );
            }
        } else {
            cal = this.defaultServices.get( cls.getName() );
            try {
                return cls.cast( cal.call() );
            } catch ( Exception e ) {
                throw new IllegalArgumentException( "Unable to instantiate service for Class '" + (cls != null ? cls.getName() : null) + "'",
                        e );
            }
        }
    }
}
